package instant.mail;

import java.io.File;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;

public class PlaybackActivity extends Activity implements Button.OnClickListener, Recorder.OnStateChangedListener, OnLongClickListener {
	class MyPlayer extends Recorder {
		
		public MyPlayer(File file) {
			super();
			mRecorder = null;
			mSampleFile = file;
		}

		@Override
		public void delete() {
			//
		}
		
	}
	//
//	private static final int DIALOG_NEW_ADDRESS = 2;
//	private static final int DIALOG_PROGRESS_SENDING = 1;
//	private static final int DIALOG_EDIT = 3;
//	private static final int DIALOG_EDITGREETING = 4;
//	
//	private static final int LISTNAME_MAX_LEN = 128;
//
//	private static final int MENU_ATTACH = R.id.etalk_attach_opt_menu_id;
//
//	private static final int MENU_ATTACHPHOTO = R.id.etalk_attachphoto_opt_menu_id;
//	private static final int MENU_ATTACHVIDEO = R.id.etalk_attachvideo_opt_menu_id;
//	private static final int MENU_EDITRECIPIENTS = R.id.etalk_recipients_opt_menu_id;
//	private static final int MENU_GREETING = R.id.etalk_greeting_opt_menu_id;
//	private static final int MENU_SETTING = R.id.etalk_setting_opt_menu_id;
//	private static final int MENU_EDITTO = R.id.etalk_edit_to_opt_menu_id;
//	private static final int MENU_EDITSUBJECT = R.id.etalk_edit_subject_opt_menu_id;
//	private static final int MENU_EDITBODY = R.id.etalk_edit_body_opt_menu_id;
//	private static final int MENU_SETUP = R.id.etalk_signature_opt_menu_id;
//	
//	private static final int RC_ATTACH = 10;
//	private static final int RC_ATTACHPHOTO = RC_ATTACH + 2;
//	private static final int RC_ATTACHVIDEO = RC_ATTACH + 1;
//	private static final int RC_EDITCONTACT = 6;
//	private static final int RC_EDITRECIPIENTS = 1;
//	private static final int RC_GREETING = 3;
//	private static final int RC_SETTING = 2;
//	private static final int RC_SETUP = 5;
//	private static final int RC_VIEWATTACH = RC_ATTACH + 3;
//	private static final int RC_VOICEINPUT = 4;
	
	private static final String RECORDER_STATE_KEY = "recorder_state";
	private static final String SAMPLE_INTERRUPTED_KEY = "sample_interrupted";
	
//	private static final String SAVED_ATTACH_KEY = "saved.attach.key";
//	private static final String SAVED_ATTACHURI_KEY = "saved.attachuri.key";
//	private static final String SAVED_BODY_KEY = "saved.body.key";
//	private static final String SAVED_CONTACTID_KEY = "saved.contactid.key";
	//
//	private static final String SAVED_NAME_KEY = "saved.name.key";
//	private static final String SAVED_SUBJECT_KEY = "saved.subject.key";
//	
//	private static final String SAVED_TO_KEY = "saved.to.key";
	
	private static final String TAG = "PlaybackActivity";

//	private static final int EDIT_INDEX_TO = 0;
//
//	private static final int EDIT_INDEX_SUBJECT = 1;
//
//	private static final int EDIT_INDEX_BODY = 2;

//	private long current = System.currentTimeMillis();

//	private MenuItem editRecipientsMenuItem;
//	private MenuItem greetingMenuItem;
//	private String listname;
//
//	private Button mAcceptButton;
//	private String mAttach;
//	private TextView mAttachment;
//
//	private String mAttachUri;
//	private String mBody;
//
//	private TextView mBodyText;
//	private Button mDiscardButton;
//
	private String mErrorUiMessage = null; 
//
//	private LinearLayout mExitButtons;

	private String mExtension = FileFormats.EXT_3GPP;
	//
	private final Handler mHandler = new Handler();

//	private ImageView mHeaderImage;
//	private LinearLayout mHeaderLayout;
//	private TextView mHeaderSubject;
//	private TextView mHeaderTo;
//
//	private View mLayout;
	
	private long mMaxFileSize = Constants.AUDIO_FILE_MAX_SIZE;

	private ImageButton mPlayButton;

//	private ImageButton mRecordButton;
//	private ImageButton mRecordButton1;

//	private View mRecordButtons;
	
	private MyPlayer mRecorder;
	
	private RemainingTimeCalculator mRemainingTimeCalculator;
	//
	private String mRequestedMimeType = FileFormats.AUDIO_3GPP;
	private boolean mSampleInterrupted = false;
	
	//private BroadcastReceiver mSDCardMountEventReceiver = null;
	//
	private TextView mStateMessage1;
	
	//private TextView mStateMessage2;
	
	private ProgressBar mStateProgressBar;
	private ImageButton mStopButton;
	
	//private String mSubject;
	
	private String mTimerFormat;
	private TextView mTimerView;
	//private String mTo;
	Runnable mUpdateTimer = new Runnable() {
		public void run() {
			updateTimerView();
		}
	};
	private VUMeter mVUMeter;
	private WakeLock mWakeLock;
	
	//private Dialog newAddressDialog;
	//private boolean pendingAutoStart;
	//
	//private SendTask pendingSendTask;
	//private ProgressDialog sendProgressDialog;
	//private MenuItem settingMenuItem;

	//private Dialog editDialog;

//	private int editIndex;
//
//	private boolean greetingDirty;
//
//	private Dialog editGreetingDialog;
//
//	private MenuItem editMenuItem;
//
//	private MenuItem signatureMenuItem;
//
//	private Menu optionsMenu;

//	private boolean optionsEnabled = true;
//
//	private Drawable drawable_send32;
//
//	private Drawable drawable_save32;
//
//	private Button mSetupButton;
	
//	private void showError(Exception e) {
//		Toast.makeText(this, ""+ e.getMessage(), Toast.LENGTH_SHORT).show();
//	}
//
//
//	private void doFinish() {
//		finish();
//	}

	
//	private boolean hasRecording() {
//		return (mRecorder != null && mRecorder.sampleDuration() > 0);
//	}


	/*
	 * Whenever the UI is re-created (e.g. due to orientation change) we have
	 * to reinitialize references to the views.
	 */
	private void initResourceRefs() {
		//
		//mLayout = findViewById(R.id.etalk_compose_layout);
		//

		//
		mPlayButton = (ImageButton) findViewById(R.id.playButton);
		mStopButton = (ImageButton) findViewById(R.id.stopButton);

		//mRecordButtons = findViewById(R.id.recordButtons);
		
		mStateMessage1 = (TextView) findViewById(R.id.stateMessage1);
		mStateProgressBar = (ProgressBar) findViewById(R.id.stateProgressBar);
		mTimerView = (TextView) findViewById(R.id.timerView);

		mVUMeter = (VUMeter) findViewById(R.id.uvMeter);
		//
		mTimerFormat = getString(R.string.timer_format);
		//
		mVUMeter.setRecorder(mRecorder);
		//
		addListeners();
	}

	private void addListeners() {
		//touch
		mPlayButton.setOnClickListener(this);
		mStopButton.setOnClickListener(this);
	
		//
		//mStateMessage1.setOnClickListener(this);
		//
	}
	
//	@Override
//	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//		if (Constants.DEBUG_ENABLED) {
//			Log.d(TAG, "onActivityResult requestCode: " + requestCode  + " resultCode: " + resultCode + " == "+ RESULT_OK +  " data: " + data);
//		}
//	}

//	private void updateSettingUi() {
//		updateAudioSettings();
//		//
//		mStateMessage1.setVisibility(View.VISIBLE);
//		mStateMessage1.setText(mRequestedMimeType);
//		//
//		setBackground();
//	}

	/*
	 * Handle the buttons.
	 */
	public void onClick(View v) {
		//
		if (!v.isEnabled()) {
			return;
		}
		int id = v.getId();
		//
		switch (id) {
		case R.id.playButton:
			mRecorder.startPlayback();
			break;
		case R.id.stopButton:
			mRecorder.stop();
			break;
		default:
		}
	}
	
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onConfigurationChanged" + newConfig);
		}
		super.onConfigurationChanged(newConfig);
		//
		// we're recreating UI, subject may be out of sync
		//syncUi();
		//
		setContentView(R.layout.player);
		initResourceRefs();
		//
		updateUi();
		setBackground();
	}

	@Override
	public void onCreate(Bundle icycle) {
		super.onCreate(icycle);
		//
		//
		updateAudioSettings();
		//
		requestWindowFeature(Window.FEATURE_LEFT_ICON);

		//setTheme(android.R.style.Theme_Translucent_NoTitleBar);
		
		setTheme(android.R.style.Theme_Translucent);
		
		//
		//requestWindowFeature(Window.FEATURE_NO_TITLE);

		//
		setContentView(R.layout.player);
		
		setTitle(R.string.app_etalk);
		getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
				R.drawable.etalk25);
		//
		Uri uri = getIntent().getData();
		
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "uri: " + uri);
		}
		
		if (uri == null) {
			finish();
			return;
		}
		String path = null;
		if ("content".equals(uri.getScheme())) {
			path = Utils.getDataPath(this, uri);
		} else {
			path = uri.getPath();
		}
		
		File f = Files.toFile(path);
		
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "file: " + f);
		}
		
		if (f == null || !f.exists()) {
			finish();
			return;
		}
		
		mRecorder = new MyPlayer(f);
		
		mRecorder.setOnStateChangedListener(this);
		mRemainingTimeCalculator = new RemainingTimeCalculator();
		//
		PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
		mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,
				"EtalkActivity");
		//
		initResourceRefs();
		//
		//initMessage();
		//
		//setResult(RESULT_CANCELED);
		//registerExternalStorageListener();
		
		if (icycle != null) {
			restoreState(icycle);
		}
		
		updateUi();
		//
		
		setBackground();
		//ok, ready to roll
		
//		// prompt for recipients if not set
//		//
//		if (isSelf(to)) {
//			startRecipientsActivity();
//			return;
//		}
		//
		
		mRecorder.startPlayback();
	}

	private void updateAudioSettings() {
		//no UI update here as this is also called in onCreate before resource is initialized.
		final String def = Preferences.getAudiotFormat(this);
		//to ensure backward compatibility and have a valid value as we removed support for audio/amr
		final String mime = (FileFormats.indexOf(this, def) == -1 ? FileFormats.AUDIO_3GPP : def);
		//
		mRequestedMimeType = mime;
		mExtension = FileFormats.extension(mime);
		//
		mMaxFileSize = Preferences.getAudioMax(this);
		//
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "updateAudioSettings mimetype: " + mRequestedMimeType + " ext: " + mExtension + " max: " + mMaxFileSize);
		}
	}

//	@Override
//	protected Dialog onCreateDialog(int id) {
//		return null;
//	}
	
	private void updateAudioFormat(String mime) {
		mRequestedMimeType = mime;
    	mExtension = FileFormats.extension(mime);
    	mStateMessage1.setText(mime);
    	mStateMessage1.setVisibility(View.VISIBLE);
    	Preferences.putAudiotFormat(this, mime);
	}
	
//
//	@Override
//	public boolean onCreateOptionsMenu(Menu menu) {
//		if (Constants.DEBUG_ENABLED) {
//			Log.d(TAG, "onCreateOptionsMenu: " + menu);
//		}
//		
//		return false;
//	}

	@Override
	public void onDestroy() {
//		if (mSDCardMountEventReceiver != null) {
//			unregisterReceiver(mSDCardMountEventReceiver);
//			mSDCardMountEventReceiver = null;
//		}
		
		super.onDestroy();
	}

	public void onError(int error) {
		Resources res = getResources();

		String message = null;
		switch (error) {
		case Recorder.SDCARD_ACCESS_ERROR:
			message = res.getString(R.string.error_sdcard_access);
			break;
		case Recorder.INTERNAL_ERROR:
			message = res.getString(R.string.error_app_internal);
			break;
		}
		if (message != null) {
			new AlertDialog.Builder(this).setTitle(R.string.app_etalk)
					.setMessage(message).setPositiveButton(R.string.button_ok,
							null).setCancelable(false).show();
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			switch (mRecorder.state()) {
			case Recorder.IDLE_STATE:
				finish();
				break;
			case Recorder.PLAYING_STATE:
				mRecorder.stop();
				break;
			}
			return true;
		} else {
			return super.onKeyDown(keyCode, event);
		}
	}
	
	public boolean onLongClick(View v) {
		return false;
	}

//	@Override
//	public boolean onOptionsItemSelected(MenuItem item) {
//		if (Constants.DEBUG_ENABLED) {
//			Log.d(TAG, "onOptionsItemSelected: " + item);
//		}
//		return false;
//	}

	@Override
	protected void onResume() {
		super.onResume();
	}

	@Override
	protected void onPause() {
		mSampleInterrupted = (mRecorder.state() == Recorder.RECORDING_STATE);
		mRecorder.stop();
		//
		super.onPause();
	}

	@Override
	protected void onPrepareDialog(int id, Dialog v) {
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onPrepareOptionsMenu: " + menu);
		}
		return false;
	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onRestoreInstanceState: " + savedInstanceState);
		}
		super.onRestoreInstanceState(savedInstanceState);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "onSaveInstanceState: " + outState);
		}
		super.onSaveInstanceState(outState);
		//
		saveState(outState);
	}

	/*
	 * Called when Recorder changed it's state.
	 */
	public void onStateChanged(int state) {
		if (state == Recorder.PLAYING_STATE
				|| state == Recorder.RECORDING_STATE) {
			mSampleInterrupted = false;
			mErrorUiMessage = null;
		}

		if (state == Recorder.RECORDING_STATE) {
			mWakeLock.acquire(); // we don't want to go to sleep while recording
		} else {
			if (mWakeLock.isHeld()) {
				mWakeLock.release();
			}
		}
		updateUi();
	}

	@Override
	public void onStop() {
		//
		mRecorder.stop();
		super.onStop();
	}

//	/*
//	 * Registers an intent to listen for ACTION_MEDIA_EJECT/ACTION_MEDIA_MOUNTED
//	 * notifications.
//	 */
//	private void registerExternalStorageListener() {
//		if (mSDCardMountEventReceiver == null) {
//			mSDCardMountEventReceiver = new BroadcastReceiver() {
//				@Override
//				public void onReceive(Context context, Intent intent) {
//					String act = intent.getAction();
//					if (Intent.ACTION_MEDIA_EJECT.equals(act)) {
//						mRecorder.delete();
//					} else if (Intent.ACTION_MEDIA_MOUNTED.equals(act)) {
//						mSampleInterrupted = false;
//						updateUi();
//					}
//				}
//			};
//			IntentFilter iFilter = new IntentFilter();
//			iFilter.addAction(Intent.ACTION_MEDIA_EJECT);
//			iFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);
//			iFilter.addDataScheme("file");
//			registerReceiver(mSDCardMountEventReceiver, iFilter);
//		}
//	}

	private void restoreState(Bundle bundle) {
		try {
			//
			Bundle rec = bundle.getBundle(RECORDER_STATE_KEY);
			if (rec != null) {
				mRecorder.restoreState(rec);
				mSampleInterrupted = rec.getBoolean(
						SAMPLE_INTERRUPTED_KEY, false);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void saveState(Bundle bundle) {
		try {
			//
			if (mRecorder.sampleDuration() > 0) {
				Bundle rec = new Bundle();
				mRecorder.saveState(rec);
				rec.putBoolean(SAMPLE_INTERRUPTED_KEY, mSampleInterrupted);
				//
				bundle.putBundle(RECORDER_STATE_KEY, rec);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "saveState: saved: " + bundle);
		}
	}

	private void setBackground() {
		//new SetBGTask().execute();
	}


	/*
	 * Make sure we're not recording music playing in the background, ask the
	 * MediaPlaybackService to pause playback.
	 */
//	private void stopAudioPlayback() {
//		// Shamelessly copied from MediaPlaybackService.java, which
//		// should be public, but isn't.
//		Intent i = new Intent("com.android.music.musicservicecommand");
//		i.putExtra("command", "pause");
//
//		sendBroadcast(i);
//	}

	/*
	 * Called when we're in recording state. Find out how much longer we can go
	 * on recording. If it's under 5 minutes, we display a count-down in the UI.
	 * If we've run out of time, stop the recording.
	 */
	private void updateTimeRemaining() {
		long t = mRemainingTimeCalculator.timeRemaining();
		if (t <= 0) {
			mSampleInterrupted = true;
			int limit = mRemainingTimeCalculator.currentLowerLimit();
			switch (limit) {
			case RemainingTimeCalculator.DISK_SPACE_LIMIT:
				mErrorUiMessage = getResources().getString(
						R.string.storage_is_full);
				break;
			case RemainingTimeCalculator.FILE_SIZE_LIMIT:
				mErrorUiMessage = getResources().getString(
						R.string.max_length_reached);
				break;
			default:
				mErrorUiMessage = null;
				break;
			}

			mRecorder.stop();
			return;
		}
		//
		Resources res = getResources();
		String ts = null;
		if (t < 60) {
			ts = String.format(res.getString(R.string.sec_available), t);
		} else if (t < 540) {
			ts = String.format(res.getString(R.string.min_available), (t / 60 + 1));
		}
		if (ts != null) {
			//mStateMessage2.setText(ts);
		}
		long len = mRemainingTimeCalculator.currentSize();
		String sz = (len / 1024 + 1) + " KB";
		mStateMessage1.setText(sz);
	}

	/**
	 * Update the big MM:SS timer. If we are in playback, also update the
	 * progress bar.
	 */
	private void updateTimerView() {
		// Resources res = getResources();
		int state = mRecorder.state();

		boolean ongoing = (state == Recorder.RECORDING_STATE || state == Recorder.PLAYING_STATE);

		long time = ongoing ? mRecorder.progress() : mRecorder.sampleDuration();
		String timeStr = String.format(mTimerFormat, time / 60, time % 60);
		mTimerView.setText(timeStr);

		if (state == Recorder.PLAYING_STATE) {
			mStateProgressBar.setProgress((int) (100 * time / mRecorder
					.sampleDuration()));
		} else if (state == Recorder.RECORDING_STATE) {
			updateTimeRemaining();
		}

		if (ongoing) {
			mHandler.postDelayed(mUpdateTimer, 1000);
		}
	}

	/**
	 * Shows/hides the appropriate child views for the new state.
	 */
	private void updateUi() {
		//Resources res = getResources();
		//
		switch (mRecorder.state()) {
		case Recorder.IDLE_STATE:
			mPlayButton.setEnabled(true);
			mPlayButton.setFocusable(true);
			mStopButton.setEnabled(false);
			mStopButton.setFocusable(false);

			//mStateMessage1.setVisibility(View.VISIBLE);
			mStateMessage1.setText(mRequestedMimeType);

			mStateProgressBar.setVisibility(View.INVISIBLE);
			
			if (mErrorUiMessage != null) {
				mStateMessage1.setText(mErrorUiMessage);
				//mStateMessage1.setVisibility(View.VISIBLE);
			}

			break;
		case Recorder.RECORDING_STATE:
			//
			break;

		case Recorder.PLAYING_STATE:
			mPlayButton.setEnabled(false);
			mPlayButton.setFocusable(false);
			mStopButton.setEnabled(true);
			mStopButton.setFocusable(true);

			mStateProgressBar.setVisibility(View.VISIBLE);
			break;
		}
		//
		updateTimerView();
		mVUMeter.invalidate();
		//
		String s = null;
		if (mRecorder == null || mRecorder.mSampleDuration == 0
				|| mRecorder.mSampleFile == null) {
			s = mRequestedMimeType;
		} else {
			long len = mRecorder.mSampleFile.length();
			s = (len / 1024) + " KB";
			//mStateMessage1.setVisibility(View.VISIBLE);
		}
		mStateMessage1.setText(s);
		//
	}	
}
